package server

import (
	"fmt"
	"gitee.com/snxamdf/wui/config"
	"gitee.com/snxamdf/wui/logs"
	"io/ioutil"
	"log"
	"net/http"
	"path/filepath"
	"strings"
)

var contentType = map[string]string{
	".css":  "text/css",
	".js":   "application/javascript",
	".html": "text/html",
	".htm":  "text/html",
	".txt":  "text/plain",
	".png":  "image/png",
	".gif":  "image/gif",
	".jpg":  "image/jpeg",
	".bmp":  "image/bmp",
	".jpeg": "image/jpeg",
	".ico":  "image/ico",
	".json": "application/json",
}

func HttpServer(ch chan int) {
	var templatePath = config.GetConfig("template")
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		var path = r.URL.Path
		var (
			byt []byte
			err error
		)
		if path == "/" {
			path = "/index.html"
		}
		var filePath string
		var isTemp = isTemplate(path)
		var isCtl = isController(path)
		//w.Header().Set("Pragma", "no-cache")
		//w.Header().Set("Cache-Control", "no-cache, no-store, max-age=0")
		//w.Header().Set("Expires", "1L")
		//logs.Debug("isTemp:", isTemp, "isCtl:", isCtl, "path:", path)
		if isTemp || isCtl {
			if ctlmp, ok := controllerMapper[path]; ok {
				ctl := &Controller{
					responose: &Response{isWrite: true, httpResponseWriter: w},
					request:   r,
				}
				if ctlmp.authorize {
					session := ctl.Session()
					if !session.getAuth() {
						ctl.StateCode(403)
						ctl.Result(403, "未授权")
					} else {
						ctlmp.cb(ctl)
					}
				} else {
					ctlmp.cb(ctl)
				}
				if ctl.html != nil && ctl.html.tplName != "" {
					if tpl, ok := htmlTemplates[ctl.html.tplName]; ok {
						if config.IsEnvDev() {
							//本地读取
							var tplPath = fmt.Sprintf("%s/%s%s", config.AppResource, config.GetConfig("template"), ctl.html.tplName)
							if html, err := ioutil.ReadFile(tplPath); err == nil {
								t := templateMust(ctl.html.tplName, string(html))
								writeHtmlTemplate(ctl.responose.httpResponseWriter, t, ctl.html.data)
							} else {
								logs.Error("HttpServer响应结果错误:", err)
							}
						} else {
							//缓存读取
							writeHtmlTemplate(ctl.responose.httpResponseWriter, tpl.template, ctl.html.data)
						}
						return
					} else {
						ctl.StateCode(911)
						ctl.Result(911, "未找到内部操作资源")
					}
				}
				if ctl.responose.isWrite {
					ctl.write()
				}
				return
			} else {
				filePath = fmt.Sprintf("%s/%s%s", config.AppResource, templatePath, path)
			}
		} else {
			filePath = fmt.Sprintf("%s%s", config.AppResource, path)
		}
		if config.IsEnvDev() {
			byt, err = ioutil.ReadFile(filePath)
		} else {
			byt, err = config.GetEFS().ReadFile(filePath)
		}
		if err != nil {
			var content = `{"code":"911","data":"未找到内部操作资源"}`
			w.Header().Set("Content-Type", "application/json")
			w.WriteHeader(404)
			_, _ = w.Write([]byte(content))
		} else {
			et := extType(path)
			if et != "" {
				if ct, ok := contentType[et]; ok {
					w.Header().Set("Content-Type", ct)
				}
			}
			w.WriteHeader(200)
			_, _ = w.Write(byt)
		}
	})
	logs.Info("环境：", config.GetEnv(), "Http 服务：", fmt.Sprintf("http://%s", config.GetConfig("addr")))
	ch <- 1
	err := http.ListenAndServe(config.GetConfig("addr"), nil)
	if err != nil {
		log.Fatal("ListenAndServer: ", err)
	}
}

func isTemplate(path string) bool {
	ext := filepath.Ext(path)
	return ext == ".html" || ext == ".vue"
}

func isController(path string) bool {
	return strings.LastIndex(strings.ToLower(path), ".") == -1
}

func extType(path string) string {
	idx := strings.LastIndex(path, ".")
	if idx != -1 {
		return path[idx:]
	}
	return ""
}
